package com.scorpio.order.service.impl;

import com.scorpio.common.exception.CustomException;
import com.scorpio.common.service.impl.BaseServiceImpl;
import com.scorpio.order.domain.OrderEntity;
import com.scorpio.order.domain.OrderSnsEntity;
import com.scorpio.order.enums.OrderStatusEmun;
import com.scorpio.order.mapper.OrderMapper;
import com.scorpio.order.service.OrderService;
import com.scorpio.order.service.OrderSnsServer;
import com.scorpio.redis.cachelock.RedisLock;
import com.scorpio.redis.cachelock.RedisLockException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class OrderServiceImpl extends BaseServiceImpl<OrderMapper, OrderEntity> implements OrderService {

    @Autowired
    private RedisLock redisLock;

    @Autowired
    private OrderSnsServer orderSnsServer;

    @Override
    public OrderEntity selectByOrderOn(String orderSn) {
        OrderEntity entity = baseDao.selectOne(getQueryWrapper().eq("order_sn", orderSn));
        if (entity == null) {
            OrderSnsEntity snsEntity = orderSnsServer.selectByOrderSn(orderSn);
            if (snsEntity != null) {
                entity = baseDao.selectById(snsEntity.getOid());
            }
        }
        return entity;
    }

    @Override
    public int update(OrderEntity entity) {
        return baseDao.updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateLoseEfficacy(String orderOn) {
        String lockKey = "update_order_status:" + orderOn;
        if (redisLock.lock(lockKey, 5)) {
            try {
                OrderEntity orderEntity = baseDao.selectOrderSn(orderOn);
                if (orderOn == null || !OrderStatusEmun.Status0.getValue().equals(orderEntity.getStatus())) {
                    return;
                }
                if (baseDao.updateLoseEfficacy(orderOn) == 0) {
                    throw new CustomException("操作失败");
                }
                return;
            } finally {
                redisLock.unlock(lockKey);
            }
        }
        throw new RedisLockException();
    }

}
